<script setup lang="ts">
import { ref, reactive, onMounted, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { useEmitt } from '@/hooks/web/useEmitt'
import { ElMessageBox, ElMessage } from 'element-plus'
import { Check, Close, Delete } from '@element-plus/icons-vue'
import { useI18n } from '@/hooks/web/useI18n'
import { saveFormData, getFormData, delFormData, getRefEntityShowText } from '@/api/develop/form'
import { useLocaleStore } from '@/store/modules/locale'
import { GeneralSelectDialog } from '@/components/Dialog'
const localeStore = useLocaleStore()
const { emitter } = useEmitt()

defineOptions({
  name: 'FormShow'
})
const { t } = useI18n()
const { currentRoute } = useRouter()
const vFormRef = ref()

const state = reactive({
  formJson: {} as any,
  formData: {} as any,
  formDef: {} as any,
  optionData: [{} as any],
  inParam: {
    pkId: null,
    formId: null,
    fromPath: '/Develop/FormManage',
    closeEmit: '',
    readonly: 0,
    preview: false
  },
  formTitle: '',
  fkValues: {} as any, //外键字段实际值
  curColId: '',
  curFieldName: '',
  lastSelectId: '',
  loading: false,
  selectDialogVisible: false
})

//页面加载事件
onMounted(async () => {
  //读取传入参数
  state.inParam.pkId = currentRoute.value.query.pkId as any
  state.inParam.formId = currentRoute.value.query.formId as any
  const readonly = currentRoute.value.query.readonly as any
  if (readonly) {
    state.inParam.readonly = 1
  }
  const preview = currentRoute.value.query.preview as any
  state.inParam.preview = preview == 1

  const fromPath = currentRoute.value.query.fromPath as any
  if (fromPath) {
    state.inParam.fromPath = fromPath
  }
  const closeEmit = currentRoute.value.query.closeEmit as any
  if (closeEmit) {
    state.inParam.closeEmit = closeEmit
  }
  //设置当前语言
  const curLang = localeStore.getCurrentLocale.lang
  vFormRef.value.changeLanguage(curLang)
  let formNameField = 'fmName'
  if (curLang == 'en') {
    formNameField = 'enName'
  } else if (curLang == 'zh_HK') {
    formNameField = 'hkName'
  }

  //加载表单设计视图JSON
  const id = state.inParam.pkId
  const data = (await getFormData(id, state.inParam.formId, state.inParam.preview)).data as any
  state.formJson = i18nJson(curLang, data.formJson)
  state.formDef = data.formDef
  state.formTitle = data.formDef[formNameField]
  vFormRef.value.setFormJson(i18nJson(curLang, data.formJson))
  //加载表单数据，如果有pkId
  //修改
  if (id) {
    state.formData = data.formData
    state.formData.status = '' + state.formData.status
  } else {
    state.formData = {} as any
  }
  await initRefFields()
  await nextTick()
  vFormRef.value.setFormData(state.formData)
})
//初始化引用的字段的显示
const initRefFields = async () => {
  const formJson = state.formJson as any
  try {
    //找表主容器控件
    let mainGrid = null as any
    for (let control of formJson.widgetList) {
      if (control.id == 'mainGrid') {
        mainGrid = control
        break
      }
    }
    for (let col of mainGrid.cols) {
      const options = col.widgetList[0].options as any
      //引用字段处理
      if (options.refEntId) {
        await dealRefField(options)
      }
    }
  } catch (err) {
    console.log('初始化引用字段显示文本时出错：' + err)
  }
}

//初如化时处理引用字段
const dealRefField = async (fOptions) => {
  const fieldName = fOptions.name
  const value = state.formData[fieldName]
  if (!value) {
    return
  }
  state.fkValues[fieldName] = value
  const refId = fOptions.refEntId
  const data = (await getRefEntityShowText(refId, value)).data
  state.formData[fieldName] = data
}

//表单视图的国际化处理，默认简体中文
const i18nJson = (curLang, formJson) => {
  if (curLang == 'zh_CN') {
    return formJson
  }
  try {
    //找表主容器控件
    let mainGrid = null as any
    for (let control of formJson.widgetList) {
      if (control.id == 'mainGrid') {
        mainGrid = control
        break
      }
    }
    for (let col of mainGrid.cols) {
      const options = col.widgetList[0].options as any
      if (curLang == 'en') {
        options.label = options.labelEn
      } else if (curLang == 'zh_HK') {
        options.label = options.labelHk
      }
    }
  } catch (err) {
    console.log('表单视图国际化时出错：' + err)
    console.log(curLang + ':' + formJson)
  } finally {
    return formJson
  }
}

// 保存记录
const save = () => {
  //获取原始表单对象
  const srcForm = vFormRef.value.getNativeForm()
  srcForm.validate(async (vaild) => {
    if (!vaild) {
      return
    }
    state.loading = true
    let form = vFormRef.value.getFormData(false)
    form._f_o_r_m_i_d_ = state.inParam.formId
    //替换表单中外键字段值
    if (state.fkValues) {
      for (const key of Object.keys(state.fkValues)) {
        form[key] = state.fkValues[key]
      }
    }
    await saveFormData(form).then((res) => {
      const result = res as any
      //保存成功
      if (result.success) {
        ElMessage.success(t('group.saveSuccess'))
        goBack()
      } else {
        ElMessageBox.alert(t(result.message))
      }
      state.loading = false
    })
  })
}

//选择引用实体弹窗，双击返回结果
const selectRefEnt = (row) => {
  //保存外键ID
  state.fkValues[state.curFieldName] = row.id
  const showFieldName = Object.keys(row)[1]
  //显示外键值
  vFormRef.value.setFieldValue(state.curFieldName, row[showFieldName])
  state.selectDialogVisible = false
}

//统一处理表单的外键表字段选择事件
const queryRefEntData = (field) => {
  const refId = field.options.refEntId
  const colId = field.options.colId
  //非外键引用字段
  if (!refId || !colId) {
    return
  }
  state.curColId = colId
  const fieldName = field.options.name
  state.curFieldName = fieldName
  state.lastSelectId = state.fkValues[fieldName]
  state.selectDialogVisible = true
}

//删除记录
const deleteThis = () => {
  let tips = t('form.deleteTip')
  ElMessageBox.confirm(tips, t('entity.confirm'), {
    type: 'warning'
  }).then(() => {
    delFormData(state.inParam.pkId, state.inParam.formId).then((res) => {
      const result = res as any
      if (!res) {
        return
      }
      //删除成功
      if (result.success) {
        if (state.inParam.closeEmit) {
          //刷新列表
          emitter.emit(state.inParam.closeEmit)
        }
        ElMessage.success(t(result.message))
        goBack()
        return
      }
    })
  })
}

// 返回列表
const goBack = () => {
  emitter.emit('closeTag', {
    closePath: currentRoute.value.fullPath,
    backPath: state.inParam.fromPath
  })
}
</script>
<template>
  <div>
    <!-- 卡片表頭 -->
    <el-card class="box-card">
      <template #header>
        <div class="card-header">
          <span>{{ state.formTitle + (state.inParam.preview ? $t('form.preview') : '') }}</span>
        </div>
      </template>
      <div>
        <v-form-render
          :previewState="true"
          :option-data="state.optionData"
          ref="vFormRef"
          @append-button-click="queryRefEntData"
        />
      </div>
      <div class="detailFooter">
        <el-button type="primary" plain @click="save" :loading="state.loading">
          <el-icon><Check /></el-icon>&nbsp;{{ $t('common.save') }}
        </el-button>
        <el-button
          type="danger"
          plain
          @click="deleteThis"
          v-if="state.formData.id && state.formData.status < 4"
        >
          <el-icon><Delete /></el-icon>&nbsp;{{ $t('common.delete') }}
        </el-button>
        <el-button type="info" plain @click="goBack">
          <el-icon><Close /></el-icon>&nbsp;{{ $t('form.close') }}
        </el-button>
      </div>
    </el-card>
  </div>
  <!-- 选择引用实体（外键）字段选择对话框 -->
  <GeneralSelectDialog
    v-model="state.selectDialogVisible"
    @selected="selectRefEnt"
    :col-id="state.curColId"
    :last-value="state.lastSelectId"
    :no-deleted="true"
    sortField="create_time"
    sortOrder="desc"
    @cancel="state.selectDialogVisible = false"
    width="850px"
  />
</template>
<style lang="less" scoped>
.box-card {
  .card-header {
    font-size: 16px;
    letter-spacing: 1px;
    font-weight: bold;
    text-align: center;
    padding-top: 5px;
  }
  :deep(.el-input) {
    font-size: 12px;
  }
  :deep(.el-textarea__inner) {
    height: 85px;
    font-size: 12px;
  }
}
:deep(.el-input__inner) {
  &::placeholder {
    font-size: 12px;
  }
}
:deep(.el-card__header) {
  padding: 8px;
}
.el-select-dropdown__item {
  font-size: 12px;
}
</style>
